const Program = require('./Program');

const config = require('./config.js');
let program = new Program(config.nodeUrl);

const {Buffer} = require('node:buffer');
const crypto = require('node:crypto');
const secp256k1 = require('secp256k1');
const {keccak256} = require("ethereumjs-util");
const {ethers}  = require('ethers');

const anchor = require('@coral-xyz/anchor');

const { Keypair, PublicKey } = require('@solana/web3.js');

const {
    MessageData, InboundFunctionCallData, EncodeInfo, FunctionCallData, EncodeProof
} = require('./inboundCallFunctionCallData');
const test_init = async ()=> {
    await program.initialize();
    //3oTt8X31WXAQniiNUfZBqk6WHDj8KAvPuJG4LtXkRzedGrpCZPn6Sh87XPcG2QoxoF3fkT1SzaSkjKhwULKUwiRo
}

const check = async ()=> {
    let publik = [110, 247, 4, 236, 106, 171, 170, 177, 86, 171, 233, 238, 195, 88, 22, 103, 204, 220, 239, 39, 148, 49, 42, 112, 241, 248, 24, 1, 129, 182, 122, 17, 71, 4, 5, 42, 223, 59, 33, 175, 1, 245, 232, 65, 20, 247, 35, 76, 47, 121, 130, 21, 224, 77, 21, 173, 34, 111, 121, 156, 81, 103, 126, 146]
    let publikBuffer = Buffer.from(publik);
    console.log('publikBuffer: ', publikBuffer);
    console.log('publikeBuffer: ', publikBuffer.toString('hex'))


}
const test_decode_and_verify = async ()=> {
    let encodeInfo = "haolifeng is a good man";
    let encodeInfoBuffer = Buffer.from(encodeInfo);
    const sha256hash = keccak256(encodeInfoBuffer);

    console.log('sha256hash: ', sha256hash);


 //   let userKeypair = Keypair.fromSecretKey(new Uint8Array(config.id));
 //   let use1Privkey = userKeypair.secretKey;
 //   console.log('use1Privkey: ', use1Privkey);
    let testPrivkey = [89,147,122,71,157,114,182,85,141,123,194,123,223,107,252,86,249,216,50,185,169,63,152,87,56,84,188,163,83,232,60,149]
    const user1_secp256k2_privKey = Buffer.from(testPrivkey);

    const wallet = new ethers.Wallet(user1_secp256k2_privKey);
    console.log('wallet: ', wallet.address);
    console.log('wallet.privateKey: ', wallet.privateKey);
    console.log('wallet.publicKey: ', wallet.publicKey);

    const user1_secp256k1_privKey = Buffer.from("59937a479d72b6558d7bc27bdf6bfc56f9d832b9a93f98573854bca353e83c95", 'hex');




    let signature1 = secp256k1.ecdsaSign(sha256hash, user1_secp256k2_privKey);

    let signatures = [signature1];

    await program.decode_and_verify(encodeInfoBuffer, signatures);
    //https://explorer.solana.com/tx/5NVYFpiKhmHw3dL17WhnmA4whYBaM3dgWHkfzFR6b8CjHkoXs4EN46PXE1Q1Y9uyD7bjcMnyQ3Nxe68atJ5pKcN?cluster=devnet
}

const outbound_call = async ()=> {

    let network_id =  new anchor.BN(1);
    let contract_address = Buffer.from("B9b35117b4d0124C893f9505F5a3C9e69144a3e2");
    let functionCallData = Buffer.from("hello world");
    let source_contract_address = new PublicKey('gZu7TCzvpz3QPR52n7BHgQLodARAD9KjDJVcerD4P4W')
    //source_contract_address.toBytes()
    console.log('source_contract_address: ', source_contract_address.toBuffer());


    await program.outbound_call(network_id, contract_address, functionCallData, source_contract_address.toBuffer());
    //https://explorer.solana.com/tx/CQFLd3nce8VBPfW6JUxhhbMyuHHWwvu43Nk21pyEUMPEcaxuAZgzBeKMDge5YvvG7KTGeFZ3aQGh26yV7mRDorL?cluster=devnet

}
const inbound_call = async () => {

    let data = {
        messageData: {
            message_type: 'CancelSuccess',
            nft_contract: 'CB6SZVUAFKBOSWNRD3SQ4S42DT7UN5OJ3WIAXPELZ7TNNQL444EOVKIJ',
            nft_id: 610007,
            price_token: '0000000000000000000000000000000000000000',
            price: 1e+21,
            recipent: 'BB4E992daA6a51872C15Bf9db8f072624b91D37B',
            buyer: 'GDH2EJSEBJNTIDYACUSZ3GIAQOTIMPZFXDR64S43FABLA2NOVJSA33H4'
        },
        wmbReceive: 'wmbReceive',
        evmChainId: 2147484614,
        evmScAddr: 'b9b35117b4d0124c893f9505f5a3c9e69144a3e2',
        taskId: 'fde15cce9ac7dcdc4f1b9e2142d32e0009f918f15b6cac56b7a5b7eb5c7510ba',
        networkId: 2147483796,
        contractAddr: 'CZqEB5Hu2gBx2ieBZHL3fWtde9R3dHSvjdsNgWYydzVK'
    }

    let messageData = new MessageData(data.messageData.message_type,
        data.messageData.nft_contract,
        data.messageData.nft_id,
        data.messageData.price_token,
        data.messageData.price,
        data.messageData.recipent,
        data.messageData.buyer);

    let messageDataByte = messageData.toBorshBytes();
    let funcationCallData =new FunctionCallData(data.wmbReceive, messageDataByte)
    let funcationCallDataByte = funcationCallData.toBorshBytes();

    let inbouCallData = new InboundFunctionCallData(funcationCallDataByte, data.evmChainId, data.evmScAddr);

    let inboundCallDataBytes = inbouCallData.toBorshBytes();

    let contractAddr = new PublicKey(data.contractAddr).toBuffer();
    console.log('contractAddr: ', contractAddr);
    let encodeInfo = new EncodeInfo(inboundCallDataBytes,Buffer.from(data.taskId), data.networkId, contractAddr);
    let encodeInfoBytes = encodeInfo.toBorshBytes();

    console.log('encodeInfoBytes: ', encodeInfoBytes)


    let testPrivkey = [89,147,122,71,157,114,182,85,141,123,194,123,223,107,252,86,249,216,50,185,169,63,152,87,56,84,188,163,83,232,60,149]
    const user1_secp256k2_privKey = Buffer.from(testPrivkey);

    const  sha256hash = keccak256(Buffer.from(encodeInfoBytes));

    console.log('sha256hash: ', sha256hash);

    let signature1 = secp256k1.ecdsaSign(sha256hash, user1_secp256k2_privKey);


    let signatures = [signature1];
    console.log('signatures: ', signatures);

    let encodeProof = new EncodeProof(signatures);

    let encodeProofBuff = encodeProof.toBorshBytes();
    console.log('encodeProofBuff: ', encodeProofBuff)

    let back_encoeProof = encodeProof.fromBorshBytes(encodeProofBuff);
    console.log('back_encodeProof: ', back_encoeProof);
    console.log('back_encodeProof: ', back_encoeProof.signatures[0].signature);


    let network_id = new anchor.BN(1);

    let testEncodeInfoBuf = Buffer.from(encodeInfoBytes);
    let testEndodeProofBuf = Buffer.from(encodeProofBuff);

    console.log('testEncodeInfoBuf.length: ', testEncodeInfoBuf.length);
    console.log('testEndodeProofBuf.length: ', testEndodeProofBuf.length)

   await program.inbound_call(network_id, testEncodeInfoBuf, testEndodeProofBuf);
    //https://explorer.solana.com/tx/66TsVZC2NWmY5n4vtpJiiy3MMWDv1r8q4VRityHP94vpXrdsKVe2ukJZvLaNeWTaVcchKuykTtkzimxGVLpRW9bH?cluster=devnet


}


const main = async ()=> {
   // await test_init();
   // await test_decode_and_verify();
    //await check();
    //await outbound_call();
    await inbound_call();
}

main();